package com.hemerasolutions.v2trainer.model.step.substep;


import javax.persistence.Entity;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;

import com.hemerasolutions.v2trainer.model.base.BaseModel;
import com.hemerasolutions.v2trainer.model.exercise.Exercise;
import com.hemerasolutions.v2trainer.model.exercise.intensity.IntensityZone;
import com.hemerasolutions.v2trainer.model.step.Step;
import com.hemerasolutions.v2trainer.model.training.statistic.TrainingStatistic;
import com.hemerasolutions.v2trainer.util.Utility;


@Entity
public class ExerciseGroupedStep extends BaseModel {

	private static final long serialVersionUID = 1L;

    @ManyToOne
    private Exercise exercise;

    @ManyToOne
    private IntensityZone intensityZone;

    @OneToOne
    private Step step;

    
	public ExerciseGroupedStep() {
		super();
	}
	
	
	public ExerciseGroupedStep(Step step) {
		super();
		this.step = step;
	}

	public ExerciseGroupedStep(ExerciseGroupedStep other, Step parent) {
		super();
		this.exercise = other.exercise;
		this.step = parent;
		this.intensityZone = parent.getParentStep().getExerciseGroupStep().getIntensityZone(this.exercise);

	}
	
	public ExerciseGroupedStep(ExerciseStep other,Step parent){
		super();
		this.id = null;
		this.exercise = other.getExercise();
		this.step = parent;
		this.intensityZone = parent.getParentStep().getExerciseGroupStep().getIntensityZone(this.exercise);
	}
	
	public String getTranslatedExercise() {

		String desc = "";
		String restTime = Utility.timeToString(this.step.getRestInterval());

		if(intensityZone != null){
			desc += desc + " " + exercise.getName() + " " + intensityZone.getName();		
		}else{
			desc = desc + " " + exercise.getName() + " " ;		
		}

		if(!restTime.equals("")){
			desc += " " + "ID: " + restTime;
		}		
	
		return desc;
	}


	public TrainingStatistic calcStatistic() {
		
		TrainingStatistic ts = new TrainingStatistic(this.step.getTrainingStep(),TrainingStatistic.EXERCISE_STATISTIC);

		ExerciseGroupStep egs = this.step.getParentStep().getExerciseGroupStep();
		long totalRest   = this.calculateRestTime();
		long totalAction = this.calculateExpentTime();

		ts.setActionTime(Utility.longToDate(totalAction));
		ts.setRestTime(Utility.longToDate(totalRest));
		ts.setTotalTime(Utility.longToDate(totalAction + totalRest));
		ts.setExecution(egs.getExecution());
		ts.setVolumeFactor(egs.getVolumeFactor());
		ts.setVolumeType(egs.getVolumeType());
		ts.setRealValue(egs.getRealValue());
		ts.setExercise(this.exercise);
		ts.setIntensityZone(this.intensityZone);
		ts.calcStatistics();
		
		return ts;
		
		
	}	
	
	private long calculateRestTime(){
    	ExerciseGroupStep egs = this.step.getParentStep().getExerciseGroupStep();

		
		if(egs.getStep().getRepetition() > 2){
			return Utility.dateToLong(step.getRestInterval()) * (egs.getStep().getRepetition() - 1);
		}else{
			return Utility.dateToLong(step.getRestInterval());
		}
	}

	
	private long calculateExpentTime() {
	  	long time = 0;
	  	
	  	if(	this.step.getParentStep().getExerciseGroupStep().getVolumeType() == null ){
	  		return 0;
	  	}
	  	
	  	String ivName = this.exercise.getModality().getTrainingType().getIntensityVolume().getName();
    	String vtName = this.step.getParentStep().getExerciseGroupStep().getVolumeType().getName();
    	ExerciseGroupStep egs = this.step.getParentStep().getExerciseGroupStep();
    	
    	if(intensityZone != null){
    		if(ivName.equals("V_TIME")){

    			time += Utility.dateToLong(intensityZone.getConcentricTime());
    			time += Utility.dateToLong(intensityZone.getEccentricTime());

    		}else if (ivName.equals("V_DISTANCE")){
    			if(vtName.equals("V_TIME")){
    				time += Utility.dateToLong(egs.getDateValue());
    			}else if(vtName.equals("V_DISTANCE")){
    				if(this.intensityZone.getRealAverageSpeed() > 0){
        				time += (long)(egs.getRealValue() / this.intensityZone.getRealAverageSpeed());
        				time *= 1000;
    				}
    			}
    		}else{
    			if(vtName.equals("V_TIME")){
    				time += Utility.dateToLong(egs.getDateValue());
    			}
    		}
    	}

		time *= step.getRepetition();

    	
    	if(vtName.equals("V_REPETITION")){
			time *= egs.getRealValue();
    	}
    	
    	return time;  
	}
	
	public boolean modZoneToIntensityZone(ExerciseGroupStep egs){
		
		IntensityZone iz = egs.getIntensityZone(this.exercise);
		
		if( iz != null){
			this.intensityZone = iz;
			return true;
		}else{
			return false;
		}
	}
	
	public Exercise getExercise() {
		return exercise;
	}


	public void setExercise(Exercise exercise) {
		this.exercise = exercise;
	}


	public IntensityZone getIntensityZone() {
		return intensityZone;
	}


	public void setIntensityZone(IntensityZone intensityZone) {
		this.intensityZone = intensityZone;
	}


	public Step getStep() {
		return step;
	}


	public void setStep(Step step) {
		this.step = step;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		result = prime * result + ((step == null) ? 0 : step.hashCode());
		return result;
	}


	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		ExerciseGroupedStep other = (ExerciseGroupedStep) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		if (step == null) {
			if (other.step != null)
				return false;
		} else if (!step.equals(other.step))
			return false;
		return true;
	}


	@Override
	public String toString() {
		return "ExerciseGroupedStep [id=" + id + ", step=" + step + "]";
	}
}
